package com.xiyuan.smartutils.template.engine.expression.operator.logic;

import com.xiyuan.smartutils.Types;
import com.xiyuan.smartutils.template.engine.VariableMap;
import com.xiyuan.smartutils.template.engine.exception.ExpressionException;
import com.xiyuan.smartutils.template.engine.expression.Expression;
import com.xiyuan.smartutils.template.engine.expression.operator.Operator;

/**
 * 或运算符(||)
 *
 * @version v1.0.0 @author lgz 2020年12月9日 新建与整理
 */
public class _Or extends Operator {
    private static final long serialVersionUID = 1L;
    private final Expression left;
    private final Expression right;
    
    private boolean isDouble = false;
    
    public _Or(String path, int line, int column, Expression left, Expression right) {
        super(path, line, column);
        this.left = left;
        this.right = right;
        this.assertSymbo("逻辑 |" + (this.isDouble ? "| " : " "), left, right);
    }
    
    @Override
    public int getType() {
        return OR;
    }
    
    public _Or setDouble(boolean isDouble) {
        this.isDouble = isDouble;
        return this;
    }
    
    @Override
    protected Object build(VariableMap variableMap) {
        Object prev = left.execute(variableMap);
        if (!Types.isBoolean(prev)) {
            throw new ExpressionException(this, "逻辑与表达式{" + this + "}格式正确，左边结果不是布尔型");
        }
        
        if (isDouble && (Boolean) prev) {
            // && 第一个值为true 结束后面的计算
            return true;// 第一个值为true 结束后面的计算
        }
        
        Object next = right.execute(variableMap);
        if (!Types.isBoolean(next)) {
            throw new ExpressionException(this, "逻辑与表达式{" + this + "}格式不正常，右边结果不是布尔型");
        }
        
        return (Boolean) prev || (Boolean) next;
    }
    
    @Override
    public String toString() {
        return new StringBuilder().append(left)
                .append(" |")
                .append(isDouble ? "|" : "")
                .append(" ")
                .append(right)
                .toString();
    }
}
